package com.frontop.terminal.util;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.frontop.terminal.entity.AwaitInform;
import com.frontop.terminal.entity.PlayList;
import com.frontop.terminal.entity.Program;
import com.frontop.terminal.entity.TerminalConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 读取json文件工具
 * </P>
 *
 * @author :CCC
 * @since :2021-05-20 14:24:00
 **/
@Component
@Slf4j
public class ReadDataUtil {

    public static final Integer PROGRAM_LIST_CODING = 0;
    public static final Integer FILE_LIST_CODING = 1;
    public static final Integer PLAYLIST_LIST_CODING = 2;
    public static final Integer AWAITINFORM_LIST_CODING = 3;
    public static final Integer TERMINAL_CONFIG_CODING = 4;
    /**
     * 编码问题，有时候对比“”时不准确，换uFEFF正常
     */
    public static final String BLANK_CHAR = "\uFEFF";
    public static String TERMINAL_CONFIG_PATH = "\\data\\TerminalConfig.json";
    public static String TERMINAL_PLAY_LIST_PATH = "\\data\\PlayList.json";
    public static String TERMINAL_FILE_PATH = "\\data\\File.json";
    public static String TERMINAL_AWAIT_INFORM_PATH = "\\data\\AwaitInform.json";
    public static String TERMINAL_PROGRAM_LIST_PATH = "\\data\\ProgramList.json";
    public static List<Program> PROGRAM_LIST;
    public static List<com.frontop.terminal.entity.File> FILE_LIST;
    public static List<PlayList> PLAYLIST_LIST;
    public static List<AwaitInform> AWAITINFORM_LIST;
    public static TerminalConfig TERMINAL_CONFIG;

    /**
     * 获取播放列表
     *
     * @return PlayList列表 -map结构
     */
    public static Map<Long, PlayList> getPlayListMap() {
        List<PlayList> lists = getPlayList();

        try {
            return Objects.requireNonNull(lists).stream().collect(Collectors.toMap(PlayList::getId, Function.identity(), (key1, key2) -> key2));

        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 获取终端配置
     *
     * @return 配置对象
     */
    public static TerminalConfig getTerminalConfig() {
        if (Objects.nonNull(TERMINAL_CONFIG)) {
            return TERMINAL_CONFIG;
        }

        try {
            TERMINAL_CONFIG = JSON.parseObject(read(TERMINAL_CONFIG_PATH), TerminalConfig.class);
            return TERMINAL_CONFIG;
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 读取本地文件
     *
     * @param path 文件位置
     * @return string
     */
    public static String read(String path) {
        //文件不存在返回null
        if (!new File(path).exists()) {
            return null;
        }

        StringBuilder json = new StringBuilder();
        try (FileInputStream inputStream = new FileInputStream(path);
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
             BufferedReader reader = new BufferedReader(inputStreamReader)) {

            String len;
            while ((len = reader.readLine()) != null) {
                json.append(len);
            }
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return json.toString();
    }

    /**
     * 获取待通知列表
     *
     * @return List<AwaitInform>
     */
    public static List<AwaitInform> getAwaitInform() {
        if (Objects.nonNull(AWAITINFORM_LIST)) {
            return AWAITINFORM_LIST;
        }

        String json = read(TERMINAL_AWAIT_INFORM_PATH);
        if (StrUtil.isEmpty(json) || BLANK_CHAR.equals(json)) {
            return null;
        }

        try {
            AWAITINFORM_LIST = JSON.parseArray(json, AwaitInform.class, ParserConfig.global);
            return AWAITINFORM_LIST;
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;

    }

    /**
     * 获取播放列表
     *
     * @return PlayList列表
     */
    public static List<PlayList> getPlayList() {
        if (Objects.nonNull(PLAYLIST_LIST)) {
            return PLAYLIST_LIST;
        }

        String json = read(TERMINAL_PLAY_LIST_PATH);
        if (StrUtil.isEmpty(json) || BLANK_CHAR.equals(json)) {
            return null;
        }

        try {
            PLAYLIST_LIST = JSON.parseArray(json, PlayList.class, ParserConfig.global);
            return PLAYLIST_LIST;
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取文件列表
     */
    public static List<com.frontop.terminal.entity.File> getFile() {
        if (Objects.nonNull(FILE_LIST)) {
            return FILE_LIST;
        }

        String json = read(TERMINAL_FILE_PATH);
        if (StrUtil.isEmpty(json) || BLANK_CHAR.equals(json)) {
            return new ArrayList<>();
        }

        try {
            FILE_LIST = JSON.parseArray(json, com.frontop.terminal.entity.File.class, ParserConfig.global);
            return FILE_LIST;
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;

    }

    /**
     * 获取文件列表
     * 返回map结构
     */
    public static Map<Long, com.frontop.terminal.entity.File> getFileMap() {
        List<com.frontop.terminal.entity.File> fileList = getFile();
        if (Objects.isNull(fileList) || fileList.isEmpty()) {
            return new HashMap<>(16);
        }

        try {
            return fileList.stream().collect(Collectors.toMap(com
                    .frontop.terminal.entity.File::getId, Function.identity(), (key1, key2) -> key2));
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;

    }

    /**
     * 获取互动程序列表
     *
     * @return list
     */
    public static List<Program> getProgramList() {
        if (Objects.nonNull(PROGRAM_LIST)) {
            return PROGRAM_LIST;
        }

        String json = read(TERMINAL_PROGRAM_LIST_PATH);
        if (StrUtil.isEmpty(json) || BLANK_CHAR.equals(json)) {
            return null;
        }

        try {
            PROGRAM_LIST = JSON.parseArray(json, Program.class, ParserConfig.global);
            return PROGRAM_LIST;
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;

    }

    /**
     * 获取互动程序列表
     *
     * @return map结构
     */
    public static Map<String, Program> getProgramListMap() {
        List<Program> lists = getProgramList();

        try {
            return Objects.requireNonNull(lists).stream().collect(Collectors.toMap(Program::getId, Function.identity(), (key1, key2) -> key2));
        } catch (Exception e) {
            log.error("读取数据时出现异常");
            e.printStackTrace();
        }

        return null;
    }

    public static void init() {
        File file = new File(ReadDataUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        String path = file.getPath();
        path = path.substring(0, 4);
        //判断生产环境还是开发环境
        String keyWord = "file";
        if (keyWord.equals(path)) {
            TERMINAL_CONFIG_PATH = System.getProperty("user.dir") + TERMINAL_CONFIG_PATH;
            TERMINAL_PLAY_LIST_PATH = System.getProperty("user.dir") + TERMINAL_PLAY_LIST_PATH;
            TERMINAL_FILE_PATH = System.getProperty("user.dir") + TERMINAL_FILE_PATH;
            TERMINAL_AWAIT_INFORM_PATH = System.getProperty("user.dir") + TERMINAL_AWAIT_INFORM_PATH;
            TERMINAL_PROGRAM_LIST_PATH = System.getProperty("user.dir") + TERMINAL_PROGRAM_LIST_PATH;
            System.out.println("当前获取生产环境配置路径：" + TERMINAL_CONFIG_PATH);
        } else {
            TERMINAL_CONFIG_PATH = ".." + TERMINAL_CONFIG_PATH;
            TERMINAL_PLAY_LIST_PATH = ".." + TERMINAL_PLAY_LIST_PATH;
            TERMINAL_FILE_PATH = ".." + TERMINAL_FILE_PATH;
            TERMINAL_AWAIT_INFORM_PATH = ".." + TERMINAL_AWAIT_INFORM_PATH;
            TERMINAL_PROGRAM_LIST_PATH = ".." + TERMINAL_PROGRAM_LIST_PATH;
        }

    }
}
